﻿// -----------------------------------------------------------------------
// <copyright file="Sharpening.cs" company="Image Processing Course Project">
// Created 31/10/2011
// </copyright>
// -----------------------------------------------------------------------

namespace ImageProcessing.IntermediateClasses
{
    using System;
    using System.Collections.Generic;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using ImageProcessing.Utilities;

    /// <summary>
    /// Class for Sharpening Operations
    /// </summary>
    public class Sharpening
    {
        /// <summary>
        /// Instance of NeighbourhoodOperations class
        /// </summary>
        private NeighbourhoodOperations neighbourhoodOp;

        /// <summary>
        /// Size of the mask to work with
        /// </summary>
        private int maskSize;

        /// <summary>
        /// Original Image to be sharpened
        /// </summary>
        private Bitmap oldImage;

        /// <summary>
        /// Initializes a new instance of the Sharpening class.
        /// </summary>
        /// <param name="oldImage">Old Image from the  main form</param>
        public Sharpening(Bitmap oldImage)
        {
            this.oldImage = oldImage;
        }

        /// <summary>
        /// Initialize mask and calls on Convolution Function
        /// </summary>
        /// <returns>Sharped image</returns>
        public Bitmap Laplacian()
        {
            this.maskSize = 3;
            this.neighbourhoodOp = new NeighbourhoodOperations(this.oldImage, this.maskSize);
            double[,] mask = new double[this.maskSize, this.maskSize];
            try
            {
                for (int i = 0; i < this.maskSize; i++)
                {
                    for (int j = 0; j < this.maskSize; j++)
                    {
                        mask[i, j] = -1;
                    }
                }

                mask[this.maskSize / 2, this.maskSize / 2] = Math.Pow(this.maskSize, 2);

                return this.neighbourhoodOp.Convolution(mask, NeighbourhoodOperations.PostProcessing.cutOff);
            }
            catch (Exception ex)
            {
                Logger.LogException(ex);
                throw;
            }
        }

        /// <summary>
        /// Initialize mask and calls on Convolution Function
        /// </summary>
        /// <returns>Image sharped with horizontal line mask</returns>
        public Bitmap HorizontalSahrpening()
        {
            this.maskSize = 3;
            this.neighbourhoodOp = new NeighbourhoodOperations(this.oldImage, this.maskSize);
            double[,] mask = new double[this.maskSize, this.maskSize];
            try
            {
                for (int i = 0; i < this.maskSize - 1; i++)
                {
                    mask[i, 1] = 1;
                }

                mask[(this.maskSize - 1), (this.maskSize / 2)] = -1;

                return this.neighbourhoodOp.Convolution(mask, NeighbourhoodOperations.PostProcessing.cutOff);
            }
            catch (Exception ex)
            {
                Logger.LogException(ex);
                throw;
            }
        }

        /// <summary>
        /// Initialize mask and calls on Convolution Function
        /// </summary>
        /// <returns>Image sharped with vertical line mask</returns>
        public Bitmap VericalSahrpening()
        {
            this.maskSize = 3;
            this.neighbourhoodOp = new NeighbourhoodOperations(this.oldImage, this.maskSize);
            double[,] mask = new double[this.maskSize, this.maskSize];
            try
            {
                for (int i = 0; i < this.maskSize - 1; i++)
                {
                    mask[1, i] = 1;
                }

                mask[(this.maskSize / 2), (this.maskSize - 1)] = -1;

                return this.neighbourhoodOp.Convolution(mask, NeighbourhoodOperations.PostProcessing.cutOff);
            }
            catch (Exception ex)
            {
                Logger.LogException(ex);
                throw;
            }
        }

        /// <summary>
        /// Initialize mask and calls on Convolution Function
        /// </summary>
        /// <returns>Image sharped with diagonal'\' mask</returns>
        public Bitmap Diagonal1Sahrpening()
        {
            this.maskSize = 3;
            this.neighbourhoodOp = new NeighbourhoodOperations(this.oldImage, this.maskSize);
            double[,] mask = new double[this.maskSize, this.maskSize];
            try
            {
                mask[0, (this.maskSize - 1)] = 1;
                mask[(this.maskSize / 2), (this.maskSize / 2)] = 1;
                mask[(this.maskSize - 1), 0] = -1;

                return this.neighbourhoodOp.Convolution(mask, NeighbourhoodOperations.PostProcessing.cutOff);
            }
            catch (Exception ex)
            {
                Logger.LogException(ex);
                throw;
            }
        }

        /// <summary>
        /// Initialize mask and calls on Convolution Function
        /// </summary>
        /// <returns>Image sharped with diagonal'/' mask</returns>
        public Bitmap Diagonal2Sahrpening()
        {
            this.maskSize = 3;
            this.neighbourhoodOp = new NeighbourhoodOperations(this.oldImage, this.maskSize);
            double[,] mask = new double[this.maskSize, this.maskSize];
            try
            {
                mask[0, 0] = 1;
                mask[this.maskSize / 2, this.maskSize / 2] = 1;
                mask[(this.maskSize - 1), (this.maskSize - 1)] = -1;

                return this.neighbourhoodOp.Convolution(mask, NeighbourhoodOperations.PostProcessing.cutOff);
            }
            catch (Exception ex)
            {
                Logger.LogException(ex);
                throw;
            }
        }
    }
}
